Amazon CloudWatch Eventsを利用してECSサービスのスケールアップ・スケールダウンに対応してみた
コンニチハ、千葉です。
Amazon CloudWatch Events皆さんはもうお使いででしょうか!
今まではCloudWatch+SNS+LambdaやってきたことをCloudWatch Eventsを利用することで、イベントドリブンなアクション(Lambda実行タイミングの迅速化)したり、SNSを利用しないので構成をシンプルにできます。 (CloudWatch+SNS+Lambdaだと、ポーリングでの検知なので最大でも実行までに1分かかってしまいます)
今回は、CloudWatch Eventsを使ったECSのAutoScalingに対応してみたいと思います。
こちらを参考にやってみます。
動作イメージ図
AutoScalingをトリガーに、ECSサービスのDesiredをアップデートするLambdaファンクションが実行されるようにします。
Lambdaファンクションを作成
ECSのDesiredをアップデートするファンクションを作成します (ファンクションの作成手順は省略です)
import boto3 import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): try: # get params AutoScalingGroupName = event['AutoScalingName'] EcsClusterName = event['EcsClusterName'] EcsServiceName = event['EcsServiceName'] EcsRegion = event['EcsRegion'] client_autoscaling = boto3.client('autoscaling') response = client_autoscaling.describe_auto_scaling_groups( AutoScalingGroupNames=[ AutoScalingGroupName ], ) DesiredCapacity = response['AutoScalingGroups'][0]['DesiredCapacity'] # update ecs service client_ecs = boto3.client('ecs') response = client_ecs.update_service( cluster = EcsClusterName, service = EcsServiceName, desiredCount = DesiredCapacity ) logger.info( "EcsClusterName:" + EcsClusterName + ", EcsServiceName:" + EcsServiceName + ", DesiredCapacity:" + DesiredCapacity) except Exception as e: print(e) print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) raise e
CloudWatchの設定
ルールを作成します
- トリガー:AutoScalingによるEC2の作成成功、削除成功のタイミングを指定
- トリガーの対象として、AutoScaling名を指定
- ターゲットに、Lambdaファンクションを指定(事前に作成したLambdaファンクションを指定します)
- Lambdaのインプットにjsonを指定できるので指定(ここに対象のECSのパラメータを指定します)
インプットの例
{"AutoScalingName": "ecs-cluster-2", "EcsClusterName": "docker-build", "EcsServiceName": "sample-webapp", "EcsRegion": "ap-northeast-1" }
ポイントは、Lambdaへインプットとしてjsonを渡せます。変数としてサービス固有値を外に出すことで汎用的にLambdaファンクションを使いまわせるので便利です。
やってみた
ECSサービスの現在のDesiredの数は、「1」です。
AutoScalingの「希望(Desired)」の値を1から2に変更します。これでAutoScalingが実行され、CloudWatch EventsよりECSサービスのDesiredをアップデートするLambdaファンクションが実行されます。
Lambdaファンクションが実行され、ECSサービスのDesiredも2になっていることを確認できました。
(スケールダウン時もAutoScalingの「希望(Desired)」の値に追従して、ECSサービスのDesiredも変更されるところまで確認できています)
最後に
CloudWatch Eventsを利用することで設定も簡略化され構成もシンプルになりました。
また、イベントドリブンでAWS上のAPI操作をできるということで、かなり汎用的な実装が可能になったのではないかと思います。